package org.dreamwork.jasmine2.engine;

import org.dreamwork.misc.Base64;
import org.dreamwork.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextUserAgent;
import org.xhtmlrenderer.resource.CSSResource;
import org.xhtmlrenderer.resource.ImageResource;

import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: seth.yang
 * Date: 2010-10-12
 * Time: 18:47:38
 */
public class URLUserAgent extends ITextUserAgent {
    private String base;
    private String context;

    private String home;

    private static final Logger logger = LoggerFactory.getLogger (URLUserAgent.class);

    public URLUserAgent (ITextOutputDevice outputDevice) {
        super (outputDevice);

        home = System.getProperty ("user.dir");
        if (home.indexOf ('\\') != -1) home = home.replace ('\\', '/');
        if (home.charAt (0) == '/')  home = home.substring (1);
        if (home.charAt (home.length () - 1) != '/') home += '/';
        home = "file:/" + home;
        if (logger.isTraceEnabled ())
            logger.trace ("home = " + home);
    }

    private String processURI (String uri) {
        if (logger.isTraceEnabled ()) {
            logger.trace ("processing uri: " + uri);
        }
        if (StringUtil.isEmpty (uri)) return null;
        String lower = uri.toLowerCase ();
        String ret;
        if (uri.startsWith (home)) {
            ret = base + uri.substring (home.length ());
        } else if (lower.startsWith ("/")) {
            ret = context + uri;
        } else if (lower.startsWith ("http://") || lower.startsWith ("https://") || lower.startsWith ("ftp://")) {
            ret = uri;
        } else if (lower.startsWith ("file:/")) {
            File file = new File (uri);
            if (file.canRead ())
                ret = uri;
            else if (uri.contains ("InternalResource.jxd")) {
                int pos = uri.indexOf (context);
                ret = base + uri.substring (pos + context.length () + 1);
            } else {
                ret = base + uri;
            }
        } else if (lower.startsWith ("data:")) {
            ret = uri;
        } else {
            ret = base + uri;
        }
        if (logger.isTraceEnabled ()) {
            logger.trace ("returning uri: " + ret);
        }
        return ret;
    }

    public String getBase () {
        return base;
    }

    public void setBase (String base) {
        this.base = base;
    }

    public String getContext () {
        return context;
    }

    public void setContext (String context) {
        this.context = context;
    }

    @Override
    @SuppressWarnings ("all")
    public ImageResource getImageResource (String uri) {
        uri = processURI (uri);

        if (_imageCache.containsKey (uri)) {
            return super.getImageResource (uri);
        }

        if (!StringUtil.isEmpty (uri) && uri.startsWith ("data:")) {
            // data:image/<image-type>;base64,
            int index = uri.indexOf ("base64,");
            if (index > 0) {
                index = index + "base64,".length ();
                String base64 = uri.substring (index);
                byte[] buff = Base64.decode (base64);

                try {
                    SharedContext context = getSharedContext ();
                    com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance (buff);
                    int width = (int) image.getWidth ();
                    int height = (int) image.getHeight ();
                    int factor = context.getDotsPerPixel ();
                    image.scaleAbsolute (width * factor, height * factor);
                    ImageResource ir = new ImageResource (null, new ITextFSImage (image));
                    _imageCache.put (uri, ir);
                    return ir;
                } catch (Exception ex) {
                    throw new RuntimeException (ex);
                }
            }
        }
        return super.getImageResource (uri);
    }

    @Override
    public CSSResource getCSSResource (String uri) {
        uri = processURI (uri);
        return super.getCSSResource (uri);
    }
}